<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div></div>
  </body>
  <script>
    // 不影响作用域链，但是是一个块级的元素
    let a = "尚硅谷";

    function b() {
      console.log(a);
      // let c = 'nihao'
    }
    b();
    // console.log(c);会报错，他不能获取到块级中的元素、

    // 数组的结构赋值
    const F4 = ["赵四", "刘能", "宋小宝", "小沈阳"];
    // 结构赋值
    let [zhao, liu, song, xioa] = F4; //里面的值将一一对应
    console.log(zhao, liu, song, xioa);
    // 对象的结构赋值
    const zhaobenshan = {
      name: "赵本山",
      age: "不详",
      xiaoping: function () {
        console.log("我可以演小品");
      },
    };
    // 结构赋值重命名
    const { name: res, age: req, xiaoping: yanxi } = zhaobenshan;
    console.log(res, req, yanxi);
    yanxi();

    // 反引号
    let st = `反引号也是一个字符串哦！`;
    console.log(st, typeof st);
    let html = `<ul>
                    <li></li>
                     <li></li>
                 </ul>`;
    let lover = ["倩倩"];
    let out = `${lover[0]}我现在很喜欢他！！`;
    console.log(out);
    // 简化对象的写法
    let name = "尚硅谷";

    function change() {
      console.log("我可以被改变");
    }
    const dui = {
      name,
      change,
      // age: function() {
      //     console.log('提高技能');
      // }
      age() {
        console.log("提高技能");
      },
    };
    console.log(dui);

    function changed(age, name) {
      this.age = age;
      this.name = name;
    }
    let haode = new changed(30, "zhangsan");
    console.log(haode);
    // 与结构赋值结合使用
    function contentx({ school = "北大", age }) {
      console.log(school);
      console.log(age);
    }
    contentx({
      school: "哈佛",
      age: 34,
    });
    // 展开运算符、
    function A() {
      console.log(arguments);
    }
    A(...F4);
    // 扩展运算符的应用
    var fenghangchaunqi = ["曾毅", "玲花"];
    var xijumahua = ["沈腾", "赵四", "魏翔"];
    let fenghuangmahau = [...fenghangchaunqi, ...xijumahua];
    console.log(fenghuangmahau);
    // Symbol的应用
    const duixiagn = {
      name: "张三",
      [Symbol("down")]: function () {
        console.log("我也是独一无二的");
      },
    };

    duixiagn[Symbol("up")] = function () {
      console.log("我是独一无二的");
    };
    console.log(duixiagn);

    const log = {
      name: "lc",
      list: [
        {
          id: 1,
          age: 23,
        },
        {
          id: 2,
          age: 24,
        },
      ],
    };
    //    访问对象中的数据
    for (var k in log) {
      // console.log(k);
      console.log(log[k]);
    }
    // 使用for of 来遍历数组
    const list = ["唐僧", "孙悟空", "猪八戒", "沙僧"];

    for (let v of list) {
      console.log(v);
    }
    let iterator = list[Symbol.iterator]();
    console.log(iterator.next());
    // 迭代器自定义遍历数据
    const banji = {
      name: "终极一班",
      stus: ["xiaoming", "xiaoning", "xiaotang", "knight"],
      [Symbol.iterator]() {
        index = 0;
        let _this = this;
        return {
          next: function () {
            if (index < _this.stus.length) {
              const result = {
                value: _this.stus[index],
                done: false,
              };
              index++;
              return result;
            } else {
              return {
                value: undefined,
                done: true,
              };
            }
          },
        };
      },
    };
    // banji.stus.forEach(x => console.log(x)),直接遍历数组的每一项（不能自己控制），但是不能自定义的去遍历，不符合面向对象的思想
    for (let v of banji) {
      console.log(v);
    }
    // 迭代器的使用
    function* gen() {
      console.log("hello iterator");
      console.log("hello");
    }
    let iter = gen();
    iter.next();
    // gen().next()

    // 生成器函数
    function* gend(age) {
      console.log(age);
      console.log("111");
      let one = yield "两只老虎";
      console.log("222");
      console.log(one);
      yield "一只没有耳朵，一只没有尾巴";
      console.log("333");
      yield "真奇怪";
      console.log("444");
    }
    let tiger = gend("aa");
    // console.log(tiger.next())
    tiger.next(); //这个yield相当于将代码分成了几块，yield的每一个；就是一个分隔符，.next()只是调用函数

    tiger.next("bbb");
    // for (let v of gend()) { 遍历的是每一个代码块
    //     console.log(v);
    // }
    console.log(tiger.next()); //将代码块中的数据全都打印出来了
    // tiger.next()

    // 生成器的实例
    // 解决异步函数的解决方案，避免出现回调地狱
    // 计时器是一异步函数
    function a1() {
      setTimeout(() => {
        console.log(111);
        timer.next();
      }, 1000);
    }

    function b1() {
      setTimeout(() => {
        console.log(222);
        timer.next();
      }, 1000);
    }

    function c1() {
      setTimeout(() => {
        console.log(333);
      }, 1000);
    }
    // 定义一个生成器函数
    function* time() {
      yield a1();
      yield b1();
      yield c1();
    }
    let timer = time();
    timer.next();

    // 生成器实例2
    function A1() {
      setTimeout(() => {
        let data = "用户信息";
        timers.next(data); //这是第二次调用，数据的返回值会是上一个模块的结果
      }, 1000);
    }

    function B1() {
      setTimeout(() => {
        let data = "商品数据";
        timers.next(data); //这是第三次调用，数据的返回值会是上一个模块的结果
      }, 1000);
    }

    function C1() {
      setTimeout(() => {
        let data = "商品信息";
        timers.next(data); //这是第四次调用，数据的返回值会是上一个模块的结果
      }, 1000);
    }
    // 定义一个生成器函数
    function* Timer() {
      let One = yield A1();
      console.log(One); //获得第二次调用timer.next()传递过来的值
      let Two = yield B1();
      console.log(Two);
      let Three = yield C1();
      console.log(Three);
    }
    let timers = Timer();
    timers.next();
  </script>
</html>
